package com.whfc.fuum.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.whfc.common.enums.SysUserType;
import com.whfc.common.exception.BizException;
import com.whfc.common.result.ListData;
import com.whfc.common.result.PageData;
import com.whfc.common.result.ResultEnum;
import com.whfc.common.util.PageUtil;
import com.whfc.fuum.dao.SysDeptExtMapper;
import com.whfc.fuum.dao.SysDeptMapper;
import com.whfc.fuum.dto.*;
import com.whfc.fuum.entity.SysDept;
import com.whfc.fuum.entity.SysDeptExt;
import com.whfc.fuum.entity.SysUser;
import com.whfc.fuum.entity.WxUser;
import com.whfc.fuum.manager.SysUserManager;
import com.whfc.fuum.param.AppProjectParam;
import com.whfc.fuum.param.AppProjectPostParam;
import com.whfc.fuum.param.AppProjectUnitParam;
import com.whfc.fuum.param.ImgParam;
import com.whfc.fuum.service.AppProjectService;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@DubboService(interfaceClass = AppProjectService.class, version = "1.0.0")
public class AppProjectServiceImpl implements AppProjectService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private SysDeptMapper sysDeptMapper;
    @Autowired
    private SysUserManager sysUserManager;

    @Autowired
    private SysDeptExtMapper sysDeptExtMapper;

    @Override
    public PageData<AppProjectDTO> list(SysUser user, Integer pageNum, Integer pageSize, String keyword) throws BizException {
        List<Integer> deptIdList = getDeptIdList(user);
        if (deptIdList == null || deptIdList.isEmpty()) {
            return PageUtil.emptyPage();
        }
        PageHelper.startPage(pageNum, pageSize);
        List<SysDeptExtDTO> sysDeptExtList = sysDeptExtMapper.selectProjectListByDeptIds(deptIdList, keyword);
        PageHelper.clearPage();
        PageData<SysDeptExtDTO> pageData = PageUtil.pageData(PageInfo.of(sysDeptExtList));
        List<AppProjectDTO> list = new ArrayList<>();
        for (SysDeptExtDTO sysDeptExt : sysDeptExtList) {
            AppProjectDTO appProjectDTO = new AppProjectDTO();
            appProjectDTO.setDeptId(sysDeptExt.getDeptId());
            appProjectDTO.setName(sysDeptExt.getName());
            appProjectDTO.setTitle(sysDeptExt.getTitle());
            appProjectDTO.setLng(sysDeptExt.getLng());
            appProjectDTO.setLat(sysDeptExt.getLat());
            appProjectDTO.setAddress(sysDeptExt.getAddress());
            SysDeptExtInfoDTO sysDeptExtInfoDTO = JSON.parseObject(sysDeptExt.getExtInfo(), SysDeptExtInfoDTO.class);
            if (sysDeptExtInfoDTO != null) {
                appProjectDTO.setProjectCode(sysDeptExtInfoDTO.getProjectCode());
                appProjectDTO.setPeriod(sysDeptExtInfoDTO.getPeriod());
                appProjectDTO.setMoney(sysDeptExtInfoDTO.getMoney());
                appProjectDTO.setStartDate(sysDeptExtInfoDTO.getStartDate());
                appProjectDTO.setCompleteDate(sysDeptExtInfoDTO.getCompleteDate());
                appProjectDTO.setBuilderLicenseNum(sysDeptExtInfoDTO.getBuilderLicenseNum());
                List<AppProjectImgDTO> imgList = sysDeptExtInfoDTO.getImgList();
                if (imgList != null && !imgList.isEmpty()) {
                    appProjectDTO.setCover(imgList.get(0).getImgUrl());
                }
            }
            list.add(appProjectDTO);
        }
        PageData<AppProjectDTO> projectPageData = new PageData<>();
        projectPageData.setTotal(pageData.getTotal());
        projectPageData.setPages(pageData.getPages());
        projectPageData.setList(list);
        return projectPageData;
    }

    @Override
    public ListData<AppProjectDTO> list(SysUser user) {
        List<Integer> deptIdList = getDeptIdList(user);
        if (deptIdList == null || deptIdList.isEmpty()) {
            return new ListData<>(Collections.emptyList());
        }
        List<AppProjectDTO> list = sysDeptExtMapper.selectBasicProjectListByDeptIds(deptIdList);
        for (AppProjectDTO appProjectDTO : list) {
            if (StringUtils.hasText(appProjectDTO.getExtInfo())) {
                SysDeptExtInfoDTO sysDeptExtInfoDTO = JSON.parseObject(appProjectDTO.getExtInfo(), SysDeptExtInfoDTO.class);
                if (sysDeptExtInfoDTO!=null) {
                    List<AppProjectImgDTO> imgList = sysDeptExtInfoDTO.getImgList();
                    if (imgList != null && !imgList.isEmpty()) {
                        appProjectDTO.setCover(imgList.get(0).getImgUrl());
                    }
                }
            }
        }
        return new ListData<>(list);
    }
    @Override
    public List<AppProjectDetailDTO> listByWxUser(WxUser user) {
        SysUser userByPhone = sysUserManager.getUserByPhone(user.getPhone());
        List<Integer> deptIdList = getDeptIdList(userByPhone);
        if (deptIdList == null || deptIdList.isEmpty()) {
            return new ArrayList<>();
        }
        List<AppProjectDetailDTO> listRet = new ArrayList<>();
        deptIdList.forEach(deptId->{
            AppProjectDetailDTO detail = detail(deptId);
            listRet.add(detail);
        });

        return listRet;
    }

    @Override
    public AppProjectDetailDTO detail(Integer deptId) {
        SysDeptExtDTO sysDeptExtDTO = sysDeptExtMapper.selectDetail(deptId);
        if (sysDeptExtDTO == null) {
            SysDept sysDept = sysDeptMapper.selectByPrimaryKey(deptId);
            if (sysDept == null) {
                throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "该组织机构不存在.");
            }
            //初始化数据
            SysDeptExt sysDeptExt = new SysDeptExt();
            sysDeptExt.setDeptId(deptId);
            sysDeptExtMapper.insertSelective(sysDeptExt);
            sysDeptExtDTO = new SysDeptExtDTO();
            sysDeptExtDTO.setName(sysDept.getName());
            sysDeptExtDTO.setTitle(sysDept.getTitle());
        }

        AppProjectDetailDTO appProjectDetailDTO = new AppProjectDetailDTO();
        SysDeptExtInfoDTO extInfo = JSON.parseObject(sysDeptExtDTO.getExtInfo(), SysDeptExtInfoDTO.class);
        if (extInfo != null) {
            BeanUtils.copyProperties(extInfo, appProjectDetailDTO);
        }
        appProjectDetailDTO.setImgList(appProjectDetailDTO.getImgList() == null ? new ArrayList<>() : appProjectDetailDTO.getImgList());
        appProjectDetailDTO.setUnitList(appProjectDetailDTO.getUnitList() == null ? new ArrayList<>() : appProjectDetailDTO.getUnitList());
        appProjectDetailDTO.setPostList(appProjectDetailDTO.getPostList() == null ? new ArrayList<>() : appProjectDetailDTO.getPostList());

        appProjectDetailDTO.setDeptId(sysDeptExtDTO.getDeptId());
        appProjectDetailDTO.setName(sysDeptExtDTO.getName());
        appProjectDetailDTO.setTitle(sysDeptExtDTO.getTitle());
        appProjectDetailDTO.setLng(sysDeptExtDTO.getLng());
        appProjectDetailDTO.setLat(sysDeptExtDTO.getLat());
        if (!ObjectUtils.isEmpty(appProjectDetailDTO.getCompleteDate())) {
            Long periodWeek = DateUtil.betweenWeek(appProjectDetailDTO.getStartDate(), appProjectDetailDTO.getCompleteDate(), true);
            Long periodDay = DateUtil.betweenDay(appProjectDetailDTO.getStartDate(), appProjectDetailDTO.getCompleteDate(), true);
            Long endDays = DateUtil.betweenDay(DateUtil.date(), appProjectDetailDTO.getCompleteDate(), true);
            Long periodMonth = DateUtil.betweenMonth(appProjectDetailDTO.getStartDate(), appProjectDetailDTO.getCompleteDate(), true);
            appProjectDetailDTO.setPeriodWeek(periodWeek.intValue());
            appProjectDetailDTO.setPeriodDay(periodDay.intValue());
            appProjectDetailDTO.setPeriodMonth(periodMonth.intValue());
            appProjectDetailDTO.setEndDays(endDays.intValue());
            appProjectDetailDTO.setEndDays(periodDay.intValue()-endDays.intValue());
            long l = (periodDay - endDays)*100 / periodDay;
            BigDecimal round = NumberUtil.round(l, 0);
            appProjectDetailDTO.setPercentage(round);
        }
        return appProjectDetailDTO;
    }

    @Override
    public AppProjectDTO getByDeptId(Integer deptId) {
        SysDeptExtDTO sysDeptExtDTO = sysDeptExtMapper.selectDetail(deptId);

        AppProjectDTO appProjectDTO = new AppProjectDTO();
        if (sysDeptExtDTO == null){
            return appProjectDTO;
        }
        SysDeptExtInfoDTO extInfoDTO = JSON.parseObject(sysDeptExtDTO.getExtInfo(), SysDeptExtInfoDTO.class);
        if (extInfoDTO != null) {
            BeanUtils.copyProperties(extInfoDTO, appProjectDTO);
        }
        appProjectDTO.setDeptId(deptId);
        appProjectDTO.setName(sysDeptExtDTO.getName());
        appProjectDTO.setTitle(sysDeptExtDTO.getTitle());
        appProjectDTO.setLng(sysDeptExtDTO.getLng());
        appProjectDTO.setLat(sysDeptExtDTO.getLat());
        appProjectDTO.setAddress(sysDeptExtDTO.getAddress());
        return appProjectDTO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(AppProjectParam appProjectParam) {
        Integer deptId = appProjectParam.getDeptId();
        //获取组织机构
        SysDept sysDept = sysDeptMapper.selectByPrimaryKey(deptId);
        // 修改扩展信息
        SysDeptExt sysDeptExt = sysDeptExtMapper.selectByDeptId(deptId);
        if (sysDeptExt == null) {
            sysDeptExt = new SysDeptExt();
        }
        sysDeptExt.setDeptId(deptId);
        sysDeptExt.setLng(appProjectParam.getLng());
        sysDeptExt.setLat(appProjectParam.getLat());
        //获取扩展信息
        SysDeptExtInfoDTO extInfo = JSON.parseObject(sysDeptExt.getExtInfo(), SysDeptExtInfoDTO.class);
        if (extInfo == null) {
            extInfo = new SysDeptExtInfoDTO();
        }
        extInfo.setProjectCode(appProjectParam.getProjectCode());
        extInfo.setBuilderLicenseNum(appProjectParam.getBuilderLicenseNum());
        extInfo.setStartDate(appProjectParam.getStartDate());
        extInfo.setCompleteDate(appProjectParam.getCompleteDate());
        extInfo.setShortInfo(appProjectParam.getShortInfo());
        extInfo.setPeriod(appProjectParam.getPeriod());
        extInfo.setMoney(appProjectParam.getMoney());

        //项目图片
        List<ImgParam> imgList = appProjectParam.getImgList();
        List<AppProjectImgDTO> projectImgList = new ArrayList<>();
        if (imgList != null && !imgList.isEmpty()) {
            for (ImgParam imgParam : imgList) {
                AppProjectImgDTO appProjectImg = new AppProjectImgDTO();
                appProjectImg.setImgInfo(imgParam.getImgInfo());
                appProjectImg.setImgUrl(imgParam.getImgUrl());
                projectImgList.add(appProjectImg);
            }
            extInfo.setImgList(projectImgList);
        }

        //项目单位
        List<AppProjectUnitParam> unitList = appProjectParam.getUnitList();
        List<AppProjectUnitDTO> projectUnitList = new ArrayList<>();
        if (unitList != null && !unitList.isEmpty()) {
            for (AppProjectUnitParam unitParam : unitList) {
                AppProjectUnitDTO appProjectUnitDTO = new AppProjectUnitDTO();
                appProjectUnitDTO.setIdx(unitParam.getIdx());
                appProjectUnitDTO.setName(unitParam.getName());
                appProjectUnitDTO.setType(unitParam.getType());
                projectUnitList.add(appProjectUnitDTO);
            }
            extInfo.setUnitList(projectUnitList);
        }
        //项目岗位
        List<AppProjectPostParam> postList = appProjectParam.getPostList();
        List<AppProjectPostDTO> projectPostList = new ArrayList<>();
        if (postList != null && !postList.isEmpty()) {
            for (AppProjectPostParam postParam : postList) {
                AppProjectPostDTO appProjectPostDTO = new AppProjectPostDTO();
                appProjectPostDTO.setPost(postParam.getPost());
                appProjectPostDTO.setName(postParam.getName());
                projectPostList.add(appProjectPostDTO);
            }
            extInfo.setPostList(projectPostList);
        }
        sysDeptExt.setExtInfo(JSON.toJSONString(extInfo));
        if (sysDeptExt.getId() == null) {
            //新增
            sysDeptExtMapper.insertSelective(sysDeptExt);
        } else {
            //修改
            sysDeptExtMapper.updateByPrimaryKeySelective(sysDeptExt);
        }

        //更新简称
        sysDept.setTitle(appProjectParam.getTitle());
        sysDeptMapper.updateByPrimaryKeySelective(sysDept);
    }

    @Override
    public List<AppProjectDTO> getProjectList(List<Integer> deptIds) {
        if (deptIds == null || deptIds.isEmpty()) {
            return Collections.emptyList();
        }
        return sysDeptExtMapper.selectProjectBasicInfo(deptIds);
    }

    @Override
    public List<AppProjectDTO> getProjectList() {
        return sysDeptExtMapper.selectProjectBasicInfo(null);
    }

    @Override
    public String getProjectCustomizeField(Integer deptId) throws BizException {
        String resultStr = "";
        SysDeptExt sysDeptExt = sysDeptExtMapper.selectByDeptId(deptId);
        if (sysDeptExt == null) {
            return resultStr;
        }
        SysDeptExtInfoDTO extInfo = JSON.parseObject(sysDeptExt.getExtInfo(), SysDeptExtInfoDTO.class);
        if (extInfo == null) {
            return resultStr;
        }
        return extInfo.getJsonStr();
    }

    /**
     * 根据用户获取组织机构ID列表
     *
     * @param user 当前用户
     * @return 组织机构列表
     */
    private List<Integer> getDeptIdList(SysUser user) {

        if (user == null) {
            return new ArrayList<>();
        }
        List<SysDeptDTO> deptList;
        //内部账号
        if (SysUserType.INNER.getValue().equals(user.getType())) {
            deptList = sysDeptMapper.selectAllProject();
        }
        //客户账号
        else {
            deptList = sysDeptMapper.selectProjectListByUserId(user.getId());
        }

        return deptList.stream().map(SysDeptDTO::getId).collect(Collectors.toList());
    }
}
